package com.zerosoft.guotai.handler;

import com.zerosoft.guotai.dao.G6EventPackage;
import com.zerosoft.guotai.dao.G7EventInfo;
import com.zerosoft.guotai.dao.G7EventPackage;
import com.zerosoft.guotai.dao.GuotaiEventParse;
import lombok.SneakyThrows;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

public class GuotaiUtil {

    /**
     * 将字节数组转换为事件信息对象
     * @param buffer
     * @return
     */
    public static G7EventInfo convertTOEventInfo(byte[] buffer)
    {
        ByteBuffer bb = ByteBuffer.wrap(buffer);
        G7EventInfo eventInfo = new G7EventInfo();
        eventInfo.setVersion(bb.get());
        eventInfo.setCode(bb.get());
        eventInfo.setControllerId(bb.getShort());
        eventInfo.setLoopPanelId(bb.get());
        eventInfo.setAddress(bb.get());
        eventInfo.setChannel(bb.get());
        eventInfo.setReserved(bb.get());
        eventInfo.setDeviceType(bb.get());
        eventInfo.setPanelType(bb.get());
        eventInfo.setAlarmValue(bb.getShort());
        eventInfo.setReservedValue(bb.getShort());
        eventInfo.setBuilding(bb.getShort());
        eventInfo.setFloor(bb.get());
        eventInfo.setZone(bb.get());
        eventInfo.setYear(bb.get());
        eventInfo.setMonth(bb.get());
        eventInfo.setDay(bb.get());
        eventInfo.setHour(bb.get());
        eventInfo.setMinute(bb.get());
        eventInfo.setSecond(bb.get());
        byte[] desc = new byte[bb.remaining()];
        bb.get(desc);
        eventInfo.setDescription(new String(desc, StandardCharsets.UTF_8).trim());

        return eventInfo;
    }

    /**
     * 将字节数组转换为事件包对象
     * @param buffer
     * @return
     */
    public static G7EventPackage convertToEventPackage(byte[] buffer)
    {
        ByteBuffer bb = ByteBuffer.wrap(buffer);
        G7EventPackage eventPackage = new G7EventPackage();
        eventPackage.setTag(bb.get());
        byte length = bb.get();
        eventPackage.setLength(length);
        byte cmd = bb.get();
        eventPackage.setCommand(cmd);
        if(length- 4 > 0 && Integer.valueOf(cmd)==0x17){
            byte[] eventInfoBytes = new byte[length-4];
            bb.get(eventInfoBytes);
            eventPackage.setEventInfo(convertTOEventInfo(eventInfoBytes));
        }
        eventPackage.setCheckSum(bb.get());
        return eventPackage;
    }

    /**
     * 计算校验和
     * @param buffer
     * @return
     */
    public static byte calculateCheckSum(byte[] buffer)
    {
        int sum = 0;
        for (byte b : buffer) {
            sum += (b & 0xFF);
        }
        return (byte) (sum & 0xFF);
    }

    public static String convertToHexString(byte[] buffer,int radix)
    {
//        return new BigInteger(1, buffer).toString(radix);
        StringBuilder hexString = new StringBuilder();
        for(byte b:buffer)
        {
            hexString.append(String.format("%02"+ (radix==16?"x ":"d "), b));
        }
        return hexString.toString();
    }

    /**
     * 将字节数组转换为G6EventPackage对象
     * @param buffer
     * @return
     */
    public static G6EventPackage convertToG6EventPackage(byte[] buffer)
    {
        ByteBuffer bb = ByteBuffer.wrap(buffer);
        G6EventPackage eventPackage = new G6EventPackage();
        eventPackage.setTag(bb.getShort());
        byte length = bb.get();
        eventPackage.setLength(length);

        if(length- 4 > 0 ){
            byte[] g6EventInfo = new byte[length-4];
            bb.get(g6EventInfo);
            eventPackage.setEventParse(convertToGuotaiEventParse(g6EventInfo));
        }
        eventPackage.setCheckSum(bb.get());
        return eventPackage;

    }

    /**
     * 将字节数组转换为GuotaiEventParse对象
     * @param buffer
     * @return
     */
    @SneakyThrows
    public static GuotaiEventParse convertToGuotaiEventParse(byte[] buffer)
    {
        //TODO：需要确定数据边界,bb.remaining()来检查剩余字节数
        ByteBuffer bb = ByteBuffer.wrap(buffer);
        GuotaiEventParse eventInfo = new GuotaiEventParse();
        eventInfo.setDeviceType(Integer.valueOf(bb.get()));
        eventInfo.setEventType(Integer.valueOf(bb.get()));
        byte[] date = new byte[8];
        bb.get(date);
        eventInfo.setDate(new String(date).trim());
        byte[] time = new byte[8];
        bb.get(time);
        eventInfo.setTime(new String(time).trim());
        byte[] build = new byte[14];
        bb.get(build);
        eventInfo.setBuild(new String(build,"GB2312").trim());
        byte[] machine = new byte[4];
        bb.get(machine);
        eventInfo.setMachine(new String(machine,"GB2312").trim());
        byte[] eventNumber = new byte[14];
        bb.get(eventNumber);
        eventInfo.setEventNumber(new String(eventNumber,"GB2312").trim());
        byte[] panelTypeName = new byte[12];
        bb.get(panelTypeName);
        eventInfo.setPanelTypeName(new String(panelTypeName,"GB2312").trim());
        byte[] road = new byte[7];
        bb.get(road);
        eventInfo.setRoad(new String(road,"GB2312").trim());
        byte[] partTypeName = new byte[12];
        bb.get(partTypeName);
        eventInfo.setPartTypeName(new String(partTypeName,"GB2312").trim());
        byte[] description = new byte[24];
        bb.get(description);
        eventInfo.setDescription(new String(description,"GB2312").trim());
        byte[] position = new byte[16];
        bb.get(position);
        eventInfo.setPosition(new String(position,"GB2312").trim());

        return eventInfo;
    }
}
